using System;
using System.IO;
using System.Text.RegularExpressions;
using fit;

namespace fat
{
	public class AnnotationFixture: ColumnFixture
	{
		public String OriginalHTML;
		public int Row;
		public int Column;

		public String OverwriteCellBody;
		public String AddToCellBody;

		public String OverwriteCellTag;
		public String OverwriteEndCellTag;
		public String AddToCellTag;

		public String OverwriteRowTag;
		public String OverwriteEndRowTag;
		public String AddToRowTag;

		public String OverwriteTableTag;
		public String OverwriteEndTableTag;
		public String AddToTableTag;

		public String AddCellFollowing;
		public String RemoveFollowingCell;

		public String AddRowFollowing;
		public String RemoveFollowingRow;

		public String AddTableFollowing;

		public String ResultingHTML()
		{
			Parse table = new Parse(OriginalHTML);
			Parse row = table.at(0, Row - 1);
			Parse cell = row.at(0, Column - 1);

			if (OverwriteCellBody != null)
			{
				cell.body = OverwriteCellBody;
			}
			if (AddToCellBody != null)
			{
				cell.addToBody(AddToCellBody);
			}

			if (OverwriteCellTag != null)
			{
				cell.tag = OverwriteCellTag;
			}
			if (OverwriteEndCellTag != null)
			{
				cell.end = OverwriteEndCellTag;
			}
			if (AddToCellTag != null)
			{
				cell.addToTag(stripDelimiters(AddToCellTag));
			}

			if (OverwriteRowTag != null)
			{
				row.tag = OverwriteRowTag;
			}
			if (OverwriteEndRowTag != null)
			{
				row.end = OverwriteEndRowTag;
			}
			if (AddToRowTag != null)
			{
				row.addToTag(stripDelimiters(AddToRowTag));
			}

			if (OverwriteTableTag != null)
			{
				table.tag = OverwriteTableTag;
			}
			if (OverwriteEndTableTag != null)
			{
				table.end = OverwriteEndTableTag;
			}
			if (AddToTableTag != null)
			{
				table.addToTag(stripDelimiters(AddToTableTag));
			}

			if (AddCellFollowing != null)
			{
				addParse(cell, AddCellFollowing, new String[] {"td"});
			}
			if (RemoveFollowingCell != null)
			{
				removeParse(cell);
			}

			if (AddRowFollowing != null)
			{
				addParse(row, AddRowFollowing, new String[] {"tr", "td"});
			}
			if (RemoveFollowingRow != null)
			{
				removeParse(row);
			}

			if (AddTableFollowing != null)
			{
				addParse(table, AddTableFollowing, new String[] {"table", "tr", "td"});
			}

			return GenerateOutput(table);
		}

		void addParse(Parse parse, String newString, String[] tags)
		{
			Parse newParse = new Parse(newString, tags);
			newParse.more = parse.more;
			newParse.trailer = parse.trailer;
			parse.more = newParse;
			parse.trailer = null;
		}

		void removeParse(Parse parse)
		{
			parse.trailer = parse.more.trailer;
			parse.more = parse.more.more;
		}

		String stripDelimiters(String s)
		{
			s = Regex.Replace(s, "^\\[", "");
			s = Regex.Replace(s, "]$", "");
			return s;
		}

		// code smell note: copied from DocumentParseFixture	
		String GenerateOutput(Parse parse)
		{
			StringWriter result = new StringWriter();
			parse.print(result);
			return result.ToString().Trim();
		}
	}
}